﻿using KELT.KELTObjects.ViewportObjectModel;
using KELT.Viewport;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Threading;

namespace KELT
{
    class EncoderManager
    {
        public string sDirPath;
        private int iCount = 0;


        private string file;
        private string output;

        private List<FrameworkElement> m_frmele;

        private FrameworkElement m_CaptureWindow;

        private DispatcherTimer dispatchertimer;

        public FrameworkElement captureWindow
        {
            get
            {
                return m_CaptureWindow;
            }
            set
            {
                m_CaptureWindow = value;
            }
        }


        private TOOL mainContext;

        public EncoderManager(TOOL mainContext)
        {
            this.mainContext = mainContext;

            m_frmele = new List<FrameworkElement>();

            file = System.IO.Directory.GetCurrentDirectory() + "\\2014_03_24_17_41_55\\";
            output = System.IO.Directory.GetCurrentDirectory();
        }


        private int sec = 0;

        public void CaptureWindow(FrameworkElement captureWindow)
        {


            for (int i = 0; i < mainContext.cameraManager.pageList.Count; i++)
            {
                mainContext.mainViewport.Children.Remove(mainContext.cameraManager.pageList.ElementAt(i).FrontViusal);

            }


            this.captureWindow = captureWindow;
            sec = 0;
            iCount = 0;
            sDirPath = System.IO.Directory.GetCurrentDirectory() + "\\" + DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss");
            file = sDirPath + "\\";
            DirectoryInfo di = new DirectoryInfo(sDirPath);
            if (di.Exists == false)
            {
                di.Create();
            }
           dispatchertimer = new DispatcherTimer();
           dispatchertimer.Tick += new EventHandler(dispatchertimer_Tick);
           dispatchertimer.Interval = TimeSpan.FromSeconds(0.04);
           dispatchertimer.Start();
           
        }



        double lastTime = 0;
        void dispatchertimer_Tick(object sender, EventArgs e)
        {
            TimeSpan seekTime = new TimeSpan(0, 0, 0, (int)sec / 1000, (int)sec % 1000);

            foreach (ViewportObj textObject in mainContext.viewPortMgr.ObjectList)
            {
                if (lastTime < textObject.endTime)
                    lastTime = textObject.endTime;

                textObject.ChkObjet(mainContext, seekTime);
            }

            foreach (Page target in mainContext.cameraManager.pageList)
            {
                if (lastTime < target.endTime)
                    lastTime = target.endTime;
            }

            if (lastTime * 1000 > seekTime.Seconds * 1000 + seekTime.Milliseconds)
            {
                mainContext.viewPortMgr.myStoryboard.Begin(mainContext, true); // if the second parameter is missing or false, it doesn't work
                mainContext.viewPortMgr.myStoryboard.Seek(mainContext, seekTime, TimeSeekOrigin.BeginTime);
                mainContext.viewPortMgr.myStoryboard.Pause(mainContext); // stop doesn't work


                mainContext.cameraManager.cameraStoryboard.Begin(mainContext, true); // if the second parameter is missing or false, it doesn't work
                mainContext.cameraManager.cameraStoryboard.Seek(mainContext, seekTime, TimeSeekOrigin.BeginTime);
                mainContext.cameraManager.cameraStoryboard.Pause(mainContext); // stop doesn't work


                ImageSave(ConverterBitmapImage(this.captureWindow), sDirPath);

                //Thread.Sleep(1);
                sec += 50;


            }
            else
            {
                StopCapture();


                for (int i = 0; i < mainContext.cameraManager.pageList.Count; i++)
                {
                    mainContext.mainViewport.Children.Add(mainContext.cameraManager.pageList.ElementAt(i).FrontViusal);

                }

            }
        }


        public void ImageSave(BitmapSource source, string path)
        {
            if (source == null) return;
            BitmapEncoder encoder = null;

            FileStream stream = new FileStream(path + "\\" + iCount.ToString() + ".png", FileMode.Create, FileAccess.Write);

            // 캡쳐할때마다 카운트 증가
            ++iCount;

            encoder = new PngBitmapEncoder();


            encoder.Frames.Add(BitmapFrame.Create(source));
            encoder.Save(stream);

            stream.Close();

        }

        public void StopCapture()
        {
            dispatchertimer.Stop();

            foreach (FrameworkElement fe in m_frmele)
            {
                ImageSave(ConverterBitmapImage(fe), sDirPath);
            }

            Encoding();
        }

        public RenderTargetBitmap ConverterBitmapImage(FrameworkElement element)
        {
            try
            {
                DrawingVisual drawingVisual = new DrawingVisual();
                DrawingContext drawingContext = drawingVisual.RenderOpen();

                drawingContext.DrawRectangle(new VisualBrush(element), null, new Rect(new Point(0, 0), new Point(element.ActualWidth, element.ActualHeight)));
                drawingContext.Close();


                RenderTargetBitmap target = new RenderTargetBitmap((int)element.ActualWidth, (int)element.ActualHeight, 96, 96, System.Windows.Media.PixelFormats.Pbgra32);
                target.Render(drawingVisual);
                return target;
            }catch(Exception)
            {
                return null;
            }

        }


        public void Encoding()
        {
            ProcessStartInfo psiProInfo = new ProcessStartInfo();
            Process process = new Process();

            string strFFMPEGCmd;

            if (mainContext.soundManager.isSound)
            {
                double time = lastTime + 1;
                strFFMPEGCmd = "-t " + time + " -i \"" + mainContext.soundManager.selectSound.fileFullPath + "\" -r 15 -i \"" + file + "%d.PNG" + "\" -r 25 -acodec copy \"" + output + "\\" + DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss") + ".avi" + "\"";
            }
            else
            {
                strFFMPEGCmd = "-r 15 -i \"" + file + "%d.PNG" + "\" -r 25 -acodec copy \"" + output + "\\"+ DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss") + ".avi" +"\"";

            }



            //strFFMPEGCmd = "-r 15 -i \"" + file + "%d.PNG" + "\" -r 25 -acodec copy \"" + output + "\"";
            //strFFMPEGCmd = "-t " + time + " -i \"" + System.IO.Directory.GetCurrentDirectory() + "\\Kalimba.mp3" + "\" -r 15 -i \"" + file + "%d.PNG" + "\" -r 25 -acodec copy \"" + output + "\"";
            //strFFMPEGCmd = "-i \"" + file + "%d.PNG" + "\" -r 25 -acodec copy \"" + output + "\"";
            //strFFMPEGCmd = "-i \"" + file + "Kalimba.mp3" + "\" -i \"" + file + "%d.PNG" + "\" -acodec copy \"" + output + "\"";


            psiProInfo.Arguments = strFFMPEGCmd;

            psiProInfo.FileName = System.IO.Directory.GetCurrentDirectory() + ((Environment.Is64BitOperatingSystem) ? "\\x64" : "\\x86") + "\\ffmpeg.exe";
            psiProInfo.UseShellExecute = false;
            psiProInfo.WindowStyle = ProcessWindowStyle.Hidden;
            psiProInfo.RedirectStandardError = true;
            psiProInfo.RedirectStandardOutput = true;

            process.StartInfo = psiProInfo;
            process.Start();
        }

    }

}